/* -*- c++ -*- */

#ifndef _SEGMENT_H_
#define _SEGMENT_H_

#include "Punto.h"
#include <vector>

class Segment {
 public:
  Segment(): _ini( 0.0f, 0.0f, 0.0), _end( 0.0f, 0.0f, 0.0) {};
  Segment( const Punto &a, const Punto &b): _ini( a), _end( b) {};
  Segment( const Segment &s): _ini( s._ini), _end( s._end) {};
  ~Segment() {};

  const Punto &a() const { return _ini;}
  const Punto &b() const { return _end;}
  const Punto &ini() const { return _ini;}
  const Punto &begin() const { return _ini;}
  const Punto &end() const { return _end;}
  const Punto &p1() const { return _ini;}
  const Punto &p2() const { return _end;}
  const Punto &p() const { return _ini;}
  const Punto &q() const { return _end;}

  const Segment &operator=( const Segment &s) {
    _ini = s._ini;
    _end = s._end;
    return *this;
  }

  void set( const Punto &a, const Punto &b) {
    _ini = a;
    _end = b;
  }
  
 private:
  Punto _ini, _end;
};

// float areaTriangle( const Punto &p, const Punto &q, const Punto &r);
inline float areaTriangle( const Punto &p, const Punto &q, const Punto &r) {
  float dqpx = q.x() - p.x();
  float dqpy = q.y() - p.y();
  float drpx = r.x() - p.x();
  float drpy = r.y() - p.y();
  return 0.5f * ( dqpx * drpy - dqpy * drpx);
}

typedef enum { 
  SEG_NO_INTERSECTION = 0, 
  SEG_INTERIOR_POINT_INTERSECTION, 
  SEG_ENDPOINT_INTERSECTION, SEG_ENDPOINT_SHARED, 
  SEG_INTERIOR_SEGMENT, SEG_SEGMENT_INTERSECTION, SEG_COINCIDENT_SEGMENTS
} _t_segmentIntersectionType;

inline bool coincidentPoints( const Punto &p1, const Punto &p2, float eps) {
  Punto dif( ( p2 - p1).abs());
  // dif = absolute( dif);
  // Punto dif( fabsf( p2.x() - p1.x()), fabsf( p2.y() - p1.y()), fabsf( p2.z() - p1.z()));
  bool ret = false;
  if ( ( dif.x() < eps) && ( dif.y() < eps) && ( dif.z() < eps))
    ret = true;
  return ret;
}

const char *strSegmentIntersectionType( _t_segmentIntersectionType it);
Punto calculateLineLineIntersection2D( const Segment &s1, const Segment &s2, float eps);
_t_segmentIntersectionType checkIntersection( const Segment &s1, const Segment &s2,
					      Punto *dstPoint, Segment *dstSegment, float eps);

bool checkIntersection( const std::vector< Segment>lstSegments,
                        const Punto &src, const Punto &dst, Punto *intersec, float eps = 0.0f);

#endif // _SEGMENT_H_
